package counter.com.myservice;

import counter.com.baomidou.controller.CallbackdatainfoController;
import counter.com.baomidou.entity.Callbackdatainfo;
import counter.com.baomidou.service.ICallbackdatainfoService;
import counter.com.common.FileProperties;
import counter.com.common.UploadFileResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.Objects;

@RestController
@RequestMapping("/file")
public class FileController {
    private static final Logger logger = LoggerFactory.getLogger(FileController.class);
    @Autowired
    private FileService fileService;

    @Autowired
    private ICallbackdatainfoService callbackService;

    @Autowired
    private FileProperties fileProperties;

    @PostMapping("/upload")
    public UploadFileResponse uploadFile(@RequestParam("file") MultipartFile file) throws Exception {
        String fileName = fileService.storeFile(file);
        URLEncoder.encode(fileName, "UTF-8");
//        String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
//                .path("/file/download/")
//                .path(fileName)
//                .toUriString();
        String fileDownloadUri = fileProperties.getDownloadUrlPrefix() + fileName;

        return new UploadFileResponse(fileName, fileDownloadUri,
                file.getContentType(), file.getSize());
    }

    @GetMapping("/download/{fileName:.+}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String fileName, HttpServletRequest request) throws Exception {
        return getResourceResponseEntity(fileName, request);
    }

    @GetMapping("/callback/{fileName:.+}")
    public ResponseEntity<Resource> callbackFile(@PathVariable String fileName, HttpServletRequest request) throws Exception {
        Callbackdatainfo callbackdatainfo = new Callbackdatainfo();
        callbackdatainfo.setCreatedtime(LocalDateTime.now());
        callbackdatainfo.setType(CallbackdatainfoController.TYPE_DOWNLOAD);
        ResponseEntity<Resource> resourceResponseEntity = getResourceResponseEntity(fileName, request);
        callbackdatainfo.setSize(Objects.requireNonNull(resourceResponseEntity.getBody()).contentLength());
        callbackService.save(callbackdatainfo);
        return resourceResponseEntity;
    }

    private ResponseEntity<Resource> getResourceResponseEntity(String fileName, HttpServletRequest request) throws Exception {
        // Load file as Resource
        Resource resource = fileService.loadFileAsResource(fileName);

        // Try to determine file's content type
        String contentType = null;
        try {
            contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
        } catch (IOException ex) {
            logger.info("Could not determine file type.");
        }

        // Fallback to the default content type if type could not be determined
        if (contentType == null) {
            contentType = "application/octet-stream";
        }
        String fn = new String(resource.getFilename().getBytes("UTF-8"), "iso-8859-1");
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fn + "\"")
                .body(resource);
    }
}
